﻿using System;
using System.Collections.Generic;
using System.Data.Entity;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using NC.Cather;
using NC.Infrastructure.Domain;

namespace NC.Infrastructure.Data
{
    public class BaseRepository<TEntity> : IRepository<TEntity> where TEntity : BaseEntity
    {
        #region Fields

        private IUnitOfWork unitOfWork;
        private readonly IDbSet<TEntity> dbSet;

        #endregion

        #region Ctr

        public BaseRepository(IUnitOfWork unitOfWork)
        {
            this.unitOfWork = unitOfWork;
            this.dbSet = unitOfWork.Set<TEntity>();
        }

        #endregion

        #region Method

        public void Insert(TEntity entity)
        {
            if (entity == null)
                throw new Exception("添加模型为空！");
            dbSet.Add(entity);
        }

        public void Insert(IEnumerable<TEntity> entities)
        {
            foreach (TEntity entity in entities)
            {
                Insert(entity);
            }
        }

        public void Delete(TEntity entity)
        {
            if (entity == null)
                throw new Exception("删除模型时为空！");
            dbSet.Remove(entity);
        }

        public void Delete(IEnumerable<TEntity> entities)
        {
            foreach (TEntity entity in entities)
            {
                Delete(entity);
            }
        }

        public void Update(TEntity entity)
        {
            if (entity == null)
                throw new Exception("更新模型时为空！");
            unitOfWork.AttachEntityToContext<TEntity>(entity);
        }

        public IQueryable<TEntity> Entities
        {
            get { return this.dbSet; }
        }

        public void Update(IEnumerable<TEntity> entities)
        {
            foreach (TEntity entity in entities)
            {
                Update(entity);
            }
        }

        public TEntity Get(object id)
        {
            return dbSet.Find(id);
        }


        public IQueryable<TEntity> Get(System.Linq.Expressions.Expression<Func<TEntity, bool>> filter)
        {
            return dbSet.Where(filter).AsQueryable();
        }

        public IQueryable<TResultEntity> Get<TResultEntity>(System.Linq.Expressions.Expression<Func<TEntity, bool>> filter, System.Linq.Expressions.Expression<Func<TEntity, TResultEntity>> select)
        {
            return dbSet.Where(filter).Select(select).AsQueryable();
        }

        public IQueryable<TEntity> Include(params string[] path)
        {
            foreach (string n in path)
            {
                dbSet.Include(n);
            }
            return dbSet;
        }

        public int Commit()
        {
            return unitOfWork.Commit();
        }

        #endregion

    }
}
